package com.example.phobosMine;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;


import jebl.util.ProgressListener;

import com.biomatters.geneious.publicapi.documents.AnnotatedPluginDocument;
import com.biomatters.geneious.publicapi.documents.sequence.NucleotideSequenceDocument;
import com.biomatters.geneious.publicapi.documents.sequence.SequenceDocument;
import com.biomatters.geneious.publicapi.plugin.DocumentOperationException;
import com.biomatters.geneious.publicapi.plugin.DocumentSelectionSignature;
import com.biomatters.geneious.publicapi.plugin.GeneiousActionOptions;
import com.biomatters.geneious.publicapi.plugin.Options;
import com.biomatters.geneious.publicapi.plugin.SequenceAnnotationGenerator;
import com.biomatters.geneious.publicapi.utilities.Execution;
import com.biomatters.geneious.publicapi.utilities.FileUtilities;

public class PhobosMineAnnotationGenerator extends SequenceAnnotationGenerator {


	public static final String HELP = "a help method for PhobosMine. This is an example plugin for Geneious.";
	
	@Override
	public GeneiousActionOptions getActionOptions() {
		// Put the menu item in the find/locate bit of the Sequence menu
		return new GeneiousActionOptions("locate tandem repeats with the phobos mine plugin").setMainMenuLocation(GeneiousActionOptions.MainMenu.AnnotateAndPredict);
	}

	@Override
	public String getHelp() {
		// TODO Auto-generated method stub
		return HELP;
	}

	@Override
	public DocumentSelectionSignature[] getSelectionSignatures() {
		return new DocumentSelectionSignature[] {
				new DocumentSelectionSignature(NucleotideSequenceDocument.class,1,Integer.MAX_VALUE)
		};
	}
	
	public Options getOptions(AnnotatedPluginDocument[] documents, SequenceAnnotationGenerator.SelectionRange selectionRange) throws DocumentOperationException{
		return new PhobosOptions();
	}
	
	@Override
	public List<SequenceAnnotationGenerator.AnnotationGeneratorResult> generate(AnnotatedPluginDocument[] documents, SequenceAnnotationGenerator.SelectionRange selectionRange, ProgressListener progressListener, Options options) throws DocumentOperationException {
		List<SequenceAnnotationGenerator.AnnotationGeneratorResult> resultsList = new ArrayList<SequenceAnnotationGenerator.AnnotationGeneratorResult>();
		
		// TODO code will go in here
		PhobosOptions phobosOptions = (PhobosOptions) options;
		
		File tempFile = null;
		
		for(AnnotatedPluginDocument annotatedPluginDocument:documents){
			SequenceDocument seqDoc = (SequenceDocument) annotatedPluginDocument.getDocument();
			tempFile = writeFasta(tempFile, seqDoc);
			String[] command = phobosOptions.getCommand(tempFile.getAbsolutePath());
			
			try{
				// need a listener on the output stream
				PhobosExecutionOutputListener outputListener = new PhobosExecutionOutputListener();
				// build an Execution object
				Execution exec = new Execution(command, progressListener,outputListener,(String)null,false);
				exec.execute();
				if(exec.wasKilledByGeneious()){
					return null;
				}
				resultsList.add(outputListener.getResults());
			}catch (IOException e){
				throw new DocumentOperationException("Phobos fail: "+e.getMessage(),e);
			}catch (InterruptedException e){
				throw new DocumentOperationException("Process killed.. \b",e);
			}
		}
		
		return resultsList;
	}
	
	private File writeFasta(File tempFile, SequenceDocument seqDoc) throws DocumentOperationException{
		try {
			tempFile = FileUtilities.createTempFile("temp_phobos", ".fasta", true);
			tempFile.deleteOnExit();
			BufferedWriter out = new BufferedWriter(new FileWriter(tempFile));
			out.write(">"+seqDoc.getName()+seqDoc.getDescription()+"\n");
			out.write(seqDoc.getSequenceString().toUpperCase());
			out.close();
		}catch (IOException e){
			throw new DocumentOperationException("Failed to write FASTA file: "+e.getMessage(),e);
		}
		return tempFile;
	}

}
